#include "Map.h"
#include "../tinyxml/tinyxml.h"
#include <vector>
#include "Entity.h"
#include "Waypoint.h"
#include "Tower.h"
#include "Node.h"
#include "TileSystem.h"
#include "Avatar.h"
#include "ObjectFactory.h"
#include "ObjectManager.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"

Map::Map(void)
{
}


Map::~Map(void)
{
}

bool Map::LoadMap(const char* _pFilename, std::vector<std::vector<CWaypoint*>> &_vLanes, CTileSystem* _pTS)
{
	//CAUTION! LOAD THE MAP AT THE START OF THE GAME ALWAYS!
	CObjectFactory* pOF	= CObjectFactory::GetInstance();

	// Create a TinyXML document
	TiXmlDocument doc;

	// Attempt to load from the file
	if( doc.LoadFile( _pFilename ) == false )
		return false;

	// Access the root node (players_list)
	TiXmlElement* pRoot = doc.RootElement();

	if( pRoot == nullptr )
		return false;
		
	TiXmlElement* pItem = pRoot->FirstChildElement( "tileset" );

	while( pItem != nullptr )
	{
		int nX;
		int nY;
		int nIndex;
		const char* pText = pItem->GetText();
		if(pText==nullptr)
		{
			break;
		}
		else if( !strcmp(pText, "tile"))
		{
			//phyll up teh H4XX0RZ!
			pItem->Attribute( "x", &nX);
			pItem->Attribute( "y", &nY);
			pItem->Attribute( "index", &nIndex );
			_pTS->SetTile(nX,nY,nIndex);
		}
		else if( !strcmp(pText, "tilesetinfo"))
		{
			pItem->Attribute( "GridSizeW",	&nX );
			pItem->Attribute( "GridSizeH",	&nY );
			_pTS->SetGridSize(nX, nY);

			pItem->Attribute( "tileWidth", &nX);
			pItem->Attribute( "tileHeight", &nY);

			_pTS->SetTileHeight(nY);
			_pTS->SetTileWidth(nX);

			pItem->Attribute( "tileSetSizeX", &nX);
			pItem->Attribute( "tileSetSizeY", &nY);

			_pTS->SetTileSetHeight(nY);
			_pTS->SetTileSetWidth(nX);
			pText = pItem->Attribute("path");

			pItem->Attribute("lanes", &nIndex);

			_vLanes.resize(nIndex);

			_pTS->SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture(pText));
		}
		else
			break;
		pItem = pItem->NextSiblingElement( "tileset" );
	}

	// Iterate through the nodes to load player info
	pItem = pRoot->FirstChildElement( "item" );/*pRoot->FirstChildElement( "item" );*/

	while( pItem != nullptr )
	{
		// Create a tPlayerInfo to store data
		CEntity* pTemp;
		int nTemp;
		int nX;
		int nY;
		// Read the name
		const char* pText = pItem->GetText();
		
		if( pText == nullptr )
		{
			break;
		}
		else
		{
			if(	!strcmp(pText, "waypoint"))
			{
				pTemp = new CWaypoint;
				pTemp->SetHeight(30);
				pTemp->SetWidth(30);

				pItem->Attribute( "x", &nX);
				pItem->Attribute( "y", &nY);

				pTemp->SetPosX((float)nX);
				pTemp->SetPosY((float)nY);

				nTemp = -1;
				pItem->Attribute( "lane", &nTemp );

				if(nTemp >=0)
				{
					_vLanes[nTemp].push_back(dynamic_cast<CWaypoint*>(pTemp));
				}
				/*CObjectManager::GetInstance()->AddObject(pTemp);
				pTemp->Release();*/
			}
			else if( !strcmp(pText, "tower" ))
			{
				pItem->Attribute( "x",	&nX );
				pItem->Attribute( "y",	&nY );
				pItem->Attribute( "owner", &nTemp );
				pOF->SpawnTower(0,(float)nX,(float)nY,nTemp);
			}
			else if( !strcmp(pText, "node" ))
			{
				pItem->Attribute( "x",	&nX );
				pItem->Attribute( "y",	&nY );
				pItem->Attribute( "soulType", &nTemp );
				pOF->SpawnNode((float)nX, (float)nY, (short)nTemp);
			}
			else if( !strcmp(pText, "avatar" ))
			{
				pItem->Attribute( "x",	&nX );
				pItem->Attribute( "y",	&nY );
				pItem->Attribute( "owner", &nTemp );
				pOF->SpawnAvatar((float)nX,(float)nY,nTemp);
			}
			else
				break;

		// Move to the next player node
		pItem = pItem->NextSiblingElement( "item" );
		}
	}

		for(unsigned int j = 0; j < _vLanes.size(); ++j)
		{
			for(unsigned int i = 0; i < _vLanes[j].size(); ++i)
			{
				if(i > 0)
				{
					_vLanes[j][i]->SetPrev(_vLanes[j][i-1]);
					_vLanes[j][i-1]->SetNext(_vLanes[j][i]);
				}
				CObjectManager::GetInstance()->AddObject(_vLanes[j][i]);
				_vLanes[j][i]->Release();
			}
		}

		// Check that a player was loaded

	return true;
}